package com.gmrz.uas.plugin.cert;

import com.gmrz.uas.plugin.exception.PluginException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.*;
import java.net.Socket;

/**
 * Created by yangairong on 17/6/1.
 */
public class CASocketClient {

    private static final Logger LOG = LogManager.getLogger(CASocketClient.class);

    //0x20 +2字节长度+ p10内容  返回证书信息
    //0x21 +2字节长度+证书内容 返回
    public String getCert(String ip,int port,byte[] p10Req)throws PluginException,IOException{
        Socket socket = null;
        DataInputStream input = null;
        DataOutputStream out = null;
        try {
            //创建一个流套接字并将其连接到指定主机上的指定端口号
            socket = new Socket(ip, port);
            //设置socket连接超时时间为5s。
            socket.setSoTimeout(30*1000);
            //通过printWriter 来向服务器发送消息
            out = new DataOutputStream(socket.getOutputStream());

            //发送消息
            //报文头
            byte[] head = new byte[1];
            head[0]=0x20;
            //计算报文长度
            byte[] datalength=new byte[2];
            datalength= Convert.intToByteArray(p10Req.length);
            //P10请求报文
            //拼接请求报文
            byte[] data=new byte[3+p10Req.length];
            System.arraycopy(head, 0, data, 0, 1);
            System.arraycopy(datalength, 0, data, 1, 2);
            System.arraycopy(p10Req,0,data,3,p10Req.length);

            out.write(data);
            out.flush();

            input = new DataInputStream(socket.getInputStream());

            byte[] charBuf = new byte[800];
            int size = 0;
            size = input.read(charBuf,0,800);
            if(charBuf[0]==33){
                byte[] datalen=new byte[4];
                datalen[2]=charBuf[1];
                datalen[3]=charBuf[2];
                int len=Convert.byteArrayToInt(datalen);
                byte[] getdata=new byte[len];
                System.arraycopy(charBuf, 3, getdata, 0, len);

                return Convert.toBase64(getdata);
            }else{
                LOG.error("Failed to obtain the CA certificate. ");
                throw new PluginException("Failed to obtain the CA certificate.");
            }
        }catch (IOException e){
            LOG.error("Failed to obtain the CA certificate. ",e);
            throw new PluginException("Failed to obtain the CA certificate.");
        }finally {
            if(null != out) {
                out.close();
            }
            if(null != input) {
                input.close();
            }
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    socket = null;
                    return null;
                }
            }
        }
    }

    public static String sendMessage(String url, int port, byte[] p10Req,byte flag) {
        byte[] res = null;
        Socket socket = null;
        InputStream is = null;
        OutputStream os = null;
        try {
            byte[] head = new byte[2];
            head[0]=0x20;
            head[1]=flag;
            //计算报文长度
            byte[] datalength=new byte[2];
            datalength= Convert.intToByteArray(p10Req.length);
            //P10请求报文
            //拼接请求报文
            byte[] data=new byte[4+p10Req.length];
            System.arraycopy(head, 0, data, 0, 2);
            System.arraycopy(datalength, 0, data, 2, 2);
            System.arraycopy(p10Req,0,data,4,p10Req.length);
            socket = new Socket(url, port);
            os = socket.getOutputStream();
            os.write(data);
            os.flush();
            is = socket.getInputStream();
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int count = 0;
            do {
                count = is.read(buffer);
                bos.write(buffer, 0, count);
            } while (is.available() != 0);
            res = bos.toByteArray();
            os.close();
            is.close();
            socket.close();
            if(res[0]==33){
                byte[] datalen=new byte[4];
                datalen[2]=res[1];
                datalen[3]=res[2];
                int len=Convert.byteArrayToInt(datalen);
                byte[] getdata=new byte[len];
                System.arraycopy(res, 3, getdata, 0, len);

                return Convert.toBase64(getdata);
            }else{
                LOG.error("Failed to obtain the CA certificate. ");
                throw new PluginException("Failed to obtain the CA certificate.");
            }
        } catch (Exception ex) {
            LOG.error("sendMessage error",ex);
            ex.printStackTrace();
            try {
                if (is != null) {
                    is.close();
                }
                if (socket != null) {
                    socket.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

}

